package cz.data.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.Callable;

/**
 * 异常工具
 */
@Slf4j
public class ThrowableUtil {

    /**
     * 获取堆栈信息
     * @param throwable
     * @return
     */
    public static String getStackTrace(Throwable throwable){
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try {
            throwable.printStackTrace(pw);
            return sw.toString();
        } finally {
            pw.close();
        }
    }

    public static void throwable(ThrowableRunnable runnable) {
        throwable(runnable, true);
    }

    public static void throwable(ThrowableRunnable runnable, boolean throwException) {
        try {
            runnable.run();
        } catch (Exception e) {
            if (throwException) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void throwable(ThrowableRunnable runnable, String message) {
        try {
            runnable.run();
        } catch (Exception e) {
            log.warn("{} - {}", message, e.getMessage());
        }
    }

    public static <T> T callable(Callable<T> callable) {
        return callable(callable, true);
    }

    public static <T> T callable(Callable<T> callable, boolean throwException) {
        try {
            return callable.call();
        } catch (Exception e) {
            if (throwException) {
                throw new RuntimeException(e);
            } else {
                log.debug("callable Exception: {}", e.getMessage());
            }
        }
        return null;
    }

    public interface ThrowableRunnable {

        void run() throws Exception;
    }
}
